/*-------------------<-- Start of Description -->--------------------\ | Generate random variate from a tabled probability distribution; | | The function was writen by Duo Zhou; | |-----------------------------------------| |--------------------------------------------------------------------| |-------------------------| | Arguments Need: | | seed - seed; Required, default is the current system time; | | var - the variable to save the generated random variates; | | p - the proportion array; | | n - the dimension of the proportion array; | | lower- the lower bound; | | array- a temporary array for internal use or output purpose; | | init - this function is being used the 1st time in the current| | data step or not? default is 1: declare an array for | | use; otherwise: do not declare the array, since it was | | alreay declared earlier; | | temp0- the seed value saver; | | temp1- a variable for internal use only; | |---------------------------| |--------------------------------------------------------------------| |---------------------------------| | Example | | data one; | | array _p(3) (0.25, 0.5, 0.25); | | %_rantbl(seed=1, var=x, n=3, p=_p); | | put x _rantbl_(1) _rantbl_(2) _rantbl0_; | | do i=1 to 100000; | | %_rantbl(seed=_rantbl0_, var=x, n=3, p=_p, init=0); | | output; | | end; | | run;%print(one(obs=200)); | | Usage: _rantbl(seed=%sysfunc(datetime(), 15.), var=REQUIRED, | | n=REQUIRED, p=, lower=, array=_rantbl_, init=1, | | temp0=_rantbl0_, temp1=_rantbl1_); | \----------------------------------*/ %macro _rantbl(seed=%sysfunc(datetime(), 15.), var=REQUIRED, p=, n=REQUIRED,lower=, array=_rantbl_, temp0=_rantbl0_, temp1=_rantbl1_, init=1); /*--------------------------------------------\ | Copy Right: Duo Zhou; | | Created: 3-22-2002 6:30pm; | | Purpose: Generate random variates from a | | tabled probability distribution; | \--------------------------------------------*/ %let _nchk_=%sysfunc(rxmatch(%sysfunc(rxparse(.|$a|$A|$w)),&n)); %if (%quote(&seed) eq) or &_nchk_ or (%quote(&var) eq) %then %do; %if (%quote(&seed) eq) %then %do; %put ==> Error: This is not a valid seed!; &var=.; %end; %if &_nchk_ %then %do; %put ==> Error: &n is not a valid array size!; &var=.; %end; %if (%quote(&var) eq) %then %do; %put ==> Error: I need a valid variable name!; %end; %goto finish; %end; %else %if (&n le 1) %then %do; %put ==> Error: array size must be an integer large than 1!; %if (%length(&var)) %then %do; &var=.; %end; %end; %else %do; %if (not %sysfunc(rxmatch(%sysfunc(rxparse(_|.|$a|$A|$w)),&seed))) %then %do; drop &temp0; retain &temp0 &seed; %let seed=&temp0; %end; %if &init %then %do; drop &temp1; array &array(%eval(&n-1)) _temporary_; %if (%length(&p)) %then %do; &array(1)=&p(1); do &temp1=2 to %eval(&n-1); &array(&temp1)=&p(&temp1)+&array(&temp1-1); end; %end; %else %do; do &temp1=1 to &n-1; &array(&temp1)=&temp1/&n; end; %end; %end; call ranuni(&seed, &var); do &temp1=1 to &n-1 until(&var>1); if &var<=&array(&temp1) then &var=&temp1; end; if &var<1 then &var=&n; %if (%length(&lower)) %then &var=&var+&lower-1; %end; %finish: %mend _rantbl;